package com.uxsino.simo.collector.connections;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import lombok.Data;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.PrivAES192;
import org.snmp4j.security.PrivAES256;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.Null;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.RetrievalEvent;
import org.snmp4j.util.TableEvent;
import org.snmp4j.util.TableUtils;

import com.alibaba.fastjson.JSON;
import com.uxsino.commons.utils.DESUtil;
import com.uxsino.simo.collector.simulate.SimulateUtil;
import com.uxsino.simo.connections.AbstractConnection;
import com.uxsino.simo.connections.exception.SimoConnectionException;
import com.uxsino.simo.connections.exception.SimoQueryException;
import com.uxsino.simo.connections.target.SNMPTarget;

public class SNMPConnection extends AbstractConnection<SNMPTarget> {
    private static Logger logger = LoggerFactory.getLogger(SNMPConnection.class);

    private final static String NULL = "";

    // private final int RETRIES = 3; // 重试次数
    private final int RETRIES = 1; // 重试次数

    private final int TIMEOUT = 5000; // 超时时间

    private Snmp snmp = null;

    private PDU pdu = null;

    private TransportMapping<UdpAddress> transport = null;

    private int version = SnmpConstants.version2c;

    private Target snmp4jTarget = null;

    private OctetString securityName = null;

    private OID authenticationProtocol = null;

    private OID privacyProtocol = null;

    private OctetString authenticationPassphrase = null;

    private OctetString privacyPassphrase = null;

    @Data
    private class SnmpCmd {

        private String[] oids;

        private String[] pdus;

        SnmpCmd(String cmd, String args) {
            oids = cmd.split("(,\\n)|(,)");
            for (int i = 0; i < oids.length; i++) {
                oids[i] = oids[i].trim();
            }
            pdus = args.split(",");
            for (int i = 0; i < pdus.length; i++) {
                pdus[i] = pdus[i].trim();
            }
        }

    }

    @Override
    // public Object buildCmd(String cmdString, Map<String, String> args) {
    // return new SnmpCmd(cmdString, args.get("args"));
    public Object buildCmd(String cmdPattern, Map<String, String> args) {
        return new SnmpCmd(cmdPattern, args.get("args"));
    }

    @Override
    public int close() {
        this.state = 0;
        try {
            if (snmp != null) {
                snmp.close();
            }
        } catch (IOException e) {
            logger.error("snmp连接关闭失败：{}", e);
        } finally {
            snmp = null;
            snmp4jTarget = null;
            pdu = null;
        }
        if (transport != null) {
            try {
                transport.close();
            } catch (IOException e) {
                logger.error("snmp transport close error", e);
            } finally {
                transport = null;
            }
        }

        super.close();

        return 0;
    }

    @Override
    public int connect(SNMPTarget target) {
        super.connect(target);
        connected = false;
        this.target = target;
        state = 1;
        if (SimulateUtil.snmp) {
            if (SimulateUtil.snmpData.containsKey(target.host)) {
                connected = true;
            }
            return state;
        }
        this.version = this.target.getSnmpVersion();
        Address targetAddress = new UdpAddress(this.target.host + "/" + this.target.port);

        try {
            transport = new DefaultUdpTransportMapping();
        } catch (IOException e1) {
            logger.error("snmp conn error", e1);
            state = 0;
            return state;
        }
        // 如果该connection持有的snmp4j对象不为空则无需初始化连接
        if (this.snmp == null) {
            snmp = new Snmp(transport);

            if (SnmpConstants.version3 == this.version) {
                // 设置安全模式
                USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
                SecurityModels.getInstance().addSecurityModel(usm);
                // 构造报文
                pdu = new ScopedPDU();
                // FIXME 测试时请尝试去除下面的语句。
                ((ScopedPDU) pdu).setContextEngineID(new OctetString(this.target.getContextEngineId()));
            } else {
                // 构造报文
                pdu = new PDU();
            }
            //this.pdu.setMaxRepetitions(3000);

            // 生成目标地址对象,示例 udp:127.0.0.1/161
            // Address targetAddress = GenericAddress.parse("udp:" +
            // target.getTargetIp() + "/" + target.getPort());

            if (version == SnmpConstants.version3) {
                switch (this.target.getSecurityLevel()) {
                case SecurityLevel.AUTH_PRIV:
                    setAuth();
                    setPriv();
                    securityName = new OctetString(this.target.getUser());
                    break;
                case SecurityLevel.AUTH_NOPRIV:
                    setAuth();
                    securityName = new OctetString(this.target.getUser());
                    break;
                case SecurityLevel.NOAUTH_NOPRIV:
                    securityName = new OctetString(this.target.getUser());
                    break;
                default:
                    break;
                }
                UsmUser user = null;
                if (StringUtils.isNoneBlank(this.target.getContextEngineId())) {
                    user = new UsmUser(securityName, authenticationProtocol, authenticationPassphrase, privacyProtocol,
                        privacyPassphrase, new OctetString(this.target.getContextEngineId()));
                } else {
                    user = new UsmUser(securityName, authenticationProtocol, authenticationPassphrase, privacyProtocol,
                        privacyPassphrase);
                }
                // 添加用户
                // FIXME
                // 检查另一种写法user.getSecurityName()
                snmp.getUSM().addUser(user.getSecurityName(), user);
                this.snmp4jTarget = new UserTarget();
                // 设置安全级别
                ((UserTarget) this.snmp4jTarget).setSecurityLevel(this.target.getSecurityLevel());
                ((UserTarget) this.snmp4jTarget).setSecurityName(user.getSecurityName());
                this.snmp4jTarget.setVersion(SnmpConstants.version3);
            } else {
                this.snmp4jTarget = new CommunityTarget();

                ((CommunityTarget) this.snmp4jTarget).setCommunity(new OctetString(this.target.getReadCommunity()));
                if (version == SnmpConstants.version1) {
                    this.snmp4jTarget.setVersion(SnmpConstants.version1);
                } else {
                    this.snmp4jTarget.setVersion(SnmpConstants.version2c);
                }
            }

            // 目标对象相关设置
            this.snmp4jTarget.setAddress(targetAddress);
            if (this.target.getRetries() > 0) {
                this.snmp4jTarget.setRetries(this.target.getRetries());
            } else {
                this.snmp4jTarget.setRetries(RETRIES);
            }
            if (this.target.getTimeout() > 0) {
                this.snmp4jTarget.setTimeout(this.target.getTimeout());
            } else {
                this.snmp4jTarget.setTimeout(TIMEOUT);
            }

            try {
                snmp.listen();
                connected = true;
            } catch (IOException e) {
                logger.error(" snmp listening error ", e);
                connected = false;
                state = 0;
                return state;
            } catch (Exception e) {
                logger.error(" snmp listening error ", e);
                state = 0;
                return state;
            }
        } else {
            connected = true;
        }

        return state;
    }

    public int setWriteCommunity(SNMPTarget target) {
        ((CommunityTarget) this.snmp4jTarget).setCommunity(new OctetString(this.target.getWriteCommunity()));
        return state;
    }

    public int setReadCommunity(SNMPTarget target) {
        ((CommunityTarget) this.snmp4jTarget).setCommunity(new OctetString(this.target.getReadCommunity()));
        return state;
    }

    @Override
    public Object execCmd(Object cmdPattern) throws SimoQueryException, SimoConnectionException {
        if (!isConnected()) {
            logger.error("can not exec command for it is not connected");
            throw new SimoConnectionException("no connection valid.");
        }
        if (SimulateUtil.snmp) {
            return getSimulateData(cmdPattern);
        } else {
            SnmpCmd snmpCmd = (SnmpCmd) cmdPattern;
            String[] oids = snmpCmd.getOids();
            String[] pdus = snmpCmd.getPdus();
            return getResultByOid(oids, pdus);
        }
    }

    public boolean execWrite(String oid, Variable value) {
        if (SimulateUtil.snmp) {
            return true;
            // return getSimulateData(cmdPattern);
        } else {
            return snmpSet(oid, value);
        }
    }

    private Object getSimulateData(Object cmdPattern) {
        SnmpCmd cmd = (SnmpCmd) cmdPattern;
        String[] oids = cmd.getOids();
        Properties snmpData = SimulateUtil.snmpData.get(target.host);
        Set<Object> keys = snmpData.keySet();
        Map<String, Map<String, String>> result = new HashMap<>();
        for (String oid : oids) {
            Map<String, String> map = new HashMap<>();
            for (Object object : keys) {
                String key = object.toString();
                String oriKey = key;
                if (key.startsWith(".")) {
                    key = key.substring(1);
                }
                if (key.equals(oid.trim()) || key.startsWith(oid.trim() + ".")) {
                    String value = snmpData.getProperty(oriKey);
                    if (value.startsWith("\"") && value.endsWith("\"")) {
                        value = value.substring(1, value.length() - 1);
                    }
                    map.put(key, value.trim());
                }
            }
            result.put(oid.trim(), map);
        }
        return result;
    }

    private Map<String, Map<String, String>> getResultByOid(String[] oids, String[] pdus)
        throws SimoQueryException, SimoConnectionException {
        Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
        String pdu = "get";
        int pduLength = pdus.length;
        for (int i = 0; i < oids.length; i++) {
            if (!connected) {
                logger.warn("snmp 访问 {} 失败，放弃本次后续OID检测！", this.target.host.toString());
                break;
            }
            String oid = oids[i].trim();
            if (i < pduLength) {
                pdu = pdus[i].trim().toLowerCase();
            }
            switch (pdu) {
            case "get":
                Map<String, String> getMap = snmpGet(oid);
                if (getMap != null) {
                    map.put(oid, getMap);
                }
                break;
            case "getnext":
                Map<String, String> getNextMap = snmpGetNext(oid);
                if (getNextMap != null) {
                    map.put(oid, getNextMap);
                }
                break;
            case "getbulk":
//                Map<String, String> groupMap = snmpWalkGroup(oid);
//                if (groupMap != null) {
//                    map.put(oid, groupMap);
//                }
                if(target.getRunModel()!=null && target.getRunModel().equalsIgnoreCase("cmd")){
                    Map<String, String> groupMap1 = executeCmdGetData(oid);
                    if (groupMap1 != null) {
                        map.put(oid, groupMap1);
                    }
                }else{
                    Map<String, String> groupMap2 = snmpWalkGroup(oid);
                    if (groupMap2 != null) {
                        map.put(oid, groupMap2);
                    }
                }

                break;
            default:
                break;
            }

        }
        if (map.size() == 0) {
            throw new SimoQueryException("All oid failed, no data");
        }
        return map;
    }

    private Map<String, String> snmpGet(String oid) {
        this.pdu.clear();
        this.pdu.setType(PDU.GET);
        Map<String, String> map = new HashMap<String, String>();
        // 设置要获取的对象ID，这个OID代表远程计算机的名称
        this.pdu.add(new VariableBinding(new OID(oid)));
        ResponseEvent respEvent = null;
        try {
            respEvent = snmp.send(this.pdu, this.snmp4jTarget);
            PDU response = respEvent.getResponse();
            if (response == null) {
                connected = false;
                logger.info("snmp 访问 {} : {} 失败，协议无法连接！", this.target.host.toString(), oid);
            } else if (response.getErrorStatus() == PDU.noError) {
                VariableBinding vb = response.getVariableBindings().firstElement();
                if (Null.isExceptionSyntax(vb.getVariable().getSyntax())) {
                    logger.info("snmp 访问 {} : {} 数据为空", this.target.host.toString(), oid);
                    return map;
                }
                /* usmStatsUnsupportedSecLevels(1)、usmStatsNotInTimeWindows(2)、usmStatsUnknownUserNames(3)
                usmStatsUnknownEngineIDs(4)、usmStatsWrongDigests(5)、usmStatsDecryptionErrors(6)
                snmp V3 以上情况也会有返回值
                */
                if(vb.getOid()!=null && vb.getOid().toString().indexOf("1.3.6.1.6.3.15.1.1")>-1){
                    logger.info("snmp v3 访问 {} : {} 失败，协议无法连接！", this.target.host.toString(), oid);
                    return map;
                }
                // map.put(vb.getOid().toDottedString(),
                // vb.getVariable().toString());
                if (oid.indexOf("1.3.6.1.2.1.2.2.1.2") > -1) {
                    map.put(oid, getChinese(vb.getVariable().toString()));
                } else {
                    map.put(oid, vb.getVariable().toString());
                }
            } else {
                logger.debug("获取" + this.target.host.toString() + ":oid[{}]数据时失败,可能是由于无访问权限"
                        + ((response != null) ? ",错误信息:" + response.getErrorStatusText() : NULL),
                    oid);
                return map;
            }
        } catch (Exception e) {
            logger.error("the {} could not be send!-->{}", oid, this.snmp4jTarget.getAddress(), e);
        } finally {
            respEvent = null;
        }

        return map;
    }

    private Map<String, String> snmpGetNext(String oid) {
        this.pdu.clear();
        this.pdu.setType(PDU.GETNEXT);
        this.pdu.add(new VariableBinding(new OID(oid)));
        Map<String, String> map = new HashMap<String, String>();
        ResponseEvent respEvent = null;
        try {
            respEvent = snmp.send(this.pdu, this.snmp4jTarget);
            PDU response = respEvent.getResponse();
            if (response == null) {
                connected = false;
                logger.info("snmp 访问 {} : {} 失败，协议无法连接！", this.target.host.toString(), oid);
            }
            if (response.getErrorStatus() == PDU.noError) {
                Vector<? extends VariableBinding> vbs = response.getVariableBindings();
                for (VariableBinding vb : vbs) {
                    if (vb.getOid().toDottedString().indexOf("1.3.6.1.2.1.2.2.1.2") > -1) {
                        map.put(vb.getOid().toDottedString(), getChinese(vb.getVariable().toString()));
                    } else {
                        map.put(vb.getOid().toDottedString(), vb.getVariable().toString());
                    }
                }
            } else {
                logger.info("snmp 访问 {} : {} 失败，{}", this.target.host.toString(), oid, response.getErrorStatusText());
                return map;
            }
        } catch (Exception e) {
            logger.error("the {} could not be send!-->{}", oid, e);
            return null;
        } finally {
            respEvent = null;
        }
        return map;
    }

    private Map<String, String> snmpWalkGroup(String oid) {
        Map<String, String> result = new LinkedHashMap<String, String>();
        try {
            if (this.pdu != null) {
                this.pdu.clear();
            }
            // 使用GETBULK方式获取数据,无论什么方式取oid,都是取叶子节点，叶子节点的父节点都不会取到
            this.pdu.setType(PDU.GETBULK);
            if (version == SnmpConstants.version1) {
                this.pdu.setType(PDU.GETNEXT);
            }
            TableUtils utils = new TableUtils(snmp, new DefaultPDUFactory(pdu.getType()));// GETNEXT
            // FIXME 不清楚setMaxNumRowsPerPDU的作用？
            // only verison 1 is supported
            if (version == SnmpConstants.version1) {
                utils.setMaxNumRowsPerPDU(1); // only for GETBULK, set
                                              // max-repetitions, default is
                                              // 10,必须大约零
            }

            utils.setMaxNumRowsPerPDU(255);
            utils.setCheckLexicographicOrdering(true);
            utils.setIgnoreMaxLexicographicRowOrderingErrors(255);

            // If not null, all returned rows have an index in a range
            // (lowerBoundIndex, upperBoundIndex]
            // lowerBoundIndex,upperBoundIndex都为null时返回所有的叶子节点。
            // 必须具体到某个OID,,否则返回的结果不会在(lowerBoundIndex,
            // upperBoundIndex)之间
            List<TableEvent> list = utils.getTable(this.snmp4jTarget, new OID[] { new OID(oid) }, null, null); //
            if(list != null && list.size() == 1 && list.get(0).getStatus() == RetrievalEvent.STATUS_TIMEOUT){
                list = utils.getTable(this.snmp4jTarget, new OID[] { new OID(oid) }, null, null);
            }
            if (list == null) {
                connected = false;
                logger.info("snmp 访问 {} : {} 失败，协议无法连接！", this.target.host.toString(), oid);
            } else if (list.size() < 1) {
                logger.info("snmp 访问 {} : {} 数据为空", this.target.host.toString(), oid);
            } else {
                for (TableEvent e : list) {
                    int status = e.getStatus();
                    // 未连接上
                    if (status == RetrievalEvent.STATUS_TIMEOUT) {
                        connected = false;
                        logger.warn("snmp 访问 {} : {} 失败，协议无法连接！", this.target.host.toString(), oid);
                        continue;
                    }
                    VariableBinding[] vbs = e.getColumns();
                    if (vbs == null) {
                        continue;
                    }
                    for (VariableBinding vb : vbs) {
                        if (Null.isExceptionSyntax(vb.getVariable().getSyntax()) || vb.getOid().toString().isEmpty()) {
                            logger.info("snmp 访问 {} : {} 数据为空", this.target.host.toString(), oid);
                            continue;
                        }
                        if (vb.getOid().toDottedString().indexOf("1.3.6.1.2.1.25.2.3.1.3") > -1
                                || vb.getOid().toDottedString().indexOf("1.3.6.1.2.1.2.2.1.2") > -1) {
                            result.put(vb.getOid().toDottedString(), getChinese(vb.getVariable().toString()));
                        } else {
                            result.put(vb.getOid().toDottedString(), vb.getVariable().toString());
                        }
                    }
                }
            }

        } catch (Exception e) {
            logger.error("the {} could not be send!", oid, e);
            return result;
        }
        return result;
    }

    private boolean snmpSet(String oid, Variable value) {
        this.pdu.clear();
        this.pdu.setType(PDU.SET);
        this.pdu.add(new VariableBinding(new OID(oid), value));
        try {
            ResponseEvent respEvent = snmp.send(this.pdu, this.snmp4jTarget);
            PDU response = respEvent.getResponse();
            if (response == null || response.getErrorStatus() != PDU.noError) {
                logger.info("在" + this.target.host.toString() + ":oid[{}]写入数据[{}]失败！"
                        + ((response != null) ? ",错误信息:" + response.getErrorStatusText() : NULL),
                    oid, value);
                return false;
            }
        } catch (Exception e) {
            logger.error("the {} could not be send!", oid, e);
            return false;
        }
        return true;
    }
    /**
     * @Author Liuxh
     * @Description // 执行cmd命令获取数据
     * @Date 16:22 2020/9/14
     * @Param [oid]
     * @return java.util.Map<java.lang.String,java.lang.String>
     **/
    private Map<String, String> executeCmdGetData(String oid) {
        Map<String, String> result = new LinkedHashMap<String, String>();
        Map<String, String> tempMap = new LinkedHashMap<String, String>();
        Process ipmoProcess = null;
        InputStream is = null;
        try {
            String cmd = getCmd(target.getSnmpVersion(),oid);
            ipmoProcess = Runtime.getRuntime().exec(cmd);
            is = ipmoProcess.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String lineStr = null;
            do {
                lineStr = br.readLine();
                if (lineStr != null) {
                    String[] split = lineStr.split("=");
                    String tempOid = split[0].trim();
                    String tempVal = split[1].trim();
                    if(tempVal.startsWith("\"") && tempVal.endsWith("\"")){
                        tempVal = tempVal.substring(1,tempVal.length()-1);
                    }
                    if(tempOid.startsWith(".")){
                        tempOid = tempOid.substring(1,tempOid.length());
                    }
                    if (oid.indexOf("1.3.6.1.2.1.2.2.1.2") > -1 || oid.indexOf("1.3.6.1.2.1.25.2.3.1.3") > -1) {
                        result.put(tempOid, getChinese(tempVal));
                    }else{
                        result.put(tempOid,tempVal);
                    }
                }
            } while (lineStr != null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }


    private String getCmd(int i,String oid){
        StringBuffer cmd = new StringBuffer();
        switch(i){
            case 3:
                cmd.append(getSnmpV3Cmd(oid));
                break;
            case 0:
                cmd.append(getSnmpV1Cmd(oid));
                break;
            case 1:
                cmd.append(getSnmpV2Cmd(oid));
            default:
                break;
        }
        return cmd.toString();
    }
    private String getSnmpV3Cmd(String oid){
        switch (target.getSecurityLevel()){
            case 1:
                return "snmpwalk -v 3 -u "+target.getUser()+" -l noAuthNoPriv "+target.host+" "+oid;
            case 2:
                return "snmpwalk -v 3 -u "+target.getUser()+" -l authNoPriv -a "+target.getAuthProtocol()+" -A "+target.getAuthPassword()+" "+target.host+" "+oid;
            case 3:
                return "snmpwalk -v 3 -u "+target.getUser()+" -l authPriv -a "+target.getAuthProtocol()+" -A "+target.getAuthPassword()+" -x "+target.getPrivProtocol()+" -X "+target.getPrivPassword()+" "+target.host+" "+oid;
            default:
                break;
        }
        return null;
    }
    private String getSnmpV2Cmd(String oid){
        return "snmpwalk -v  2c -c "+target.getReadCommunity()+" -O nQe "+target.host+" "+oid;
    }
    private String getSnmpV1Cmd(String oid){
        return "snmpwalk -v  2c -c "+target.getReadCommunity()+" -O nQe "+target.host+" "+oid;
    }

    /**
     * 解决snmp4j中文乱码问题,16进制字符串转成正常的字符串
     */
    public static String getChinese(String octetString) {
        if (!octetString.matches("([0-9|a-f|A-F]{2}:){3,}[0-9|a-f|A-F]{2}")) {
            return octetString;
        }
        try {
            String[] temps = octetString.split(":");
            byte[] bs = new byte[temps.length];
            for (int i = 0; i < temps.length; i++) {
                bs[i] = (byte) Integer.parseInt(temps[i], 16);
            }
            return new String(bs, "GB2312").trim();// "GB2312"
        } catch (Exception e) {
            return octetString;
        }
    }

    private void setPriv() {
        switch (this.target.getPrivProtocol()) {
        case "des":
            privacyProtocol = PrivDES.ID;
            break;
        case "3des":
            privacyProtocol = Priv3DES.ID;
            break;
        case "aes128":
            privacyProtocol = PrivAES128.ID;
            break;
        case "aes192":
            privacyProtocol = PrivAES192.ID;
            break;
        case "aes256":
            privacyProtocol = PrivAES256.ID;
            break;
        default:
            break;
        }
        privacyPassphrase = new OctetString(this.target.getPrivPassword());
    }

    private void setAuth() {
        switch (this.target.getAuthProtocol()) {
        case "md5":
            authenticationProtocol = AuthMD5.ID;
            break;
        case "sha":
            authenticationProtocol = AuthSHA.ID;
            break;
        default:
            break;
        }
        authenticationPassphrase = new OctetString(this.target.getAuthPassword());
    }

    @Override
    public boolean testWithConnected(String cmdString, String resStart) {
        connected = false;
        if (SimulateUtil.snmp) {
            connected = SimulateUtil.snmpData.containsKey(target.host);
        } else {
            String oid = "1.3.6.1.2.1.1.2.0";
            Map<String, String> map = snmpGet(oid);
            if (map != null && !map.isEmpty()) {
                connected = true;
            }
            logger.debug(this.target.host.toString() + "->connection test result: {}", connected);
        }
        return connected;
    }

    public static void main(String[] args) throws Exception {
        SNMPConnection conn = new SNMPConnection();
        SNMPTarget target = new SNMPTarget();
        target.host = "192.168.1.116";
        target.port = 161;
        target.setReadCommunity(DESUtil.encrypt("public1"));
        conn.connect(target);
        Object o = conn.snmpWalkGroup("1.3.6.1.2.1.4.20.1.1");
        System.out.println(JSON.toJSONString(o));
        Object o1 = conn.snmpGet("1.3.6.1.2.1.1.2.0");
        System.out.println(JSON.toJSONString(o1));
        conn.close();
    }
}
